#include "../include/disk_simulator.h"
#include <fcntl.h>
#include <unistd.h>
#include <cstring>
#include <cstdlib>
#include <sys/stat.h>
#include <sys/types.h>
#include <cstdio>
#include <dlfcn.h> 

#define DISK_FILE "test.disk"
#define DISK_SIZE (1024 * 1024) // 1MB

int main() {
    void* handle = dlopen("libdisk_simulator.so", RTLD_LAZY);
    if (!handle) {
        printf("无法加载so: %s\n", dlerror());
        return 1;
    }
    // 加载C接口
    void* (*disk_create)(const char*, size_t) = (void*(*)(const char*, size_t))dlsym(handle, "disk_create");
    void  (*disk_destroy)(void*) = (void(*)(void*))dlsym(handle, "disk_destroy");
    int   (*disk_power_on)(void*) = (int(*)(void*))dlsym(handle, "disk_power_on");
    int   (*disk_power_off)(void*) = (int(*)(void*))dlsym(handle, "disk_power_off");
    int   (*disk_is_powered_on)(void*) = (int(*)(void*))dlsym(handle, "disk_is_powered_on");
    size_t(*disk_get_size)(void*) = (size_t(*)(void*))dlsym(handle, "disk_get_size");
    int   (*disk_read)(void*, size_t, void*, size_t) = (int(*)(void*, size_t, void*, size_t))dlsym(handle, "disk_read");
    int   (*disk_write)(void*, size_t, const void*, size_t) = (int(*)(void*, size_t, const void*, size_t))dlsym(handle, "disk_write");

    // 加载新增的磁盘信息查询接口
    int   (*disk_get_serial_number)(void*, char*, size_t) = (int(*)(void*, char*, size_t))dlsym(handle, "disk_get_serial_number");
    int   (*disk_get_manufacturer)(void*, char*, size_t) = (int(*)(void*, char*, size_t))dlsym(handle, "disk_get_manufacturer");
    int   (*disk_get_model)(void*, char*, size_t) = (int(*)(void*, char*, size_t))dlsym(handle, "disk_get_model");
    int   (*disk_get_firmware_version)(void*, char*, size_t) = (int(*)(void*, char*, size_t))dlsym(handle, "disk_get_firmware_version");
    int   (*disk_set_serial_number)(void*, const char*) = (int(*)(void*, const char*))dlsym(handle, "disk_set_serial_number");
    int   (*disk_set_manufacturer)(void*, const char*) = (int(*)(void*, const char*))dlsym(handle, "disk_set_manufacturer");
    int   (*disk_set_model)(void*, const char*) = (int(*)(void*, const char*))dlsym(handle, "disk_set_model");
    int   (*disk_set_firmware_version)(void*, const char*) = (int(*)(void*, const char*))dlsym(handle, "disk_set_firmware_version");

    // 加载新增的SMART信息查询接口
    int   (*disk_get_smart_attribute)(void*, int, int*, int*, int*, int*) = (int(*)(void*, int, int*, int*, int*, int*))dlsym(handle, "disk_get_smart_attribute");
    int   (*disk_set_smart_attribute)(void*, int, int, int, int, int) = (int(*)(void*, int, int, int, int, int))dlsym(handle, "disk_set_smart_attribute");
    int   (*disk_get_smart_status)(void*, int*) = (int(*)(void*, int*))dlsym(handle, "disk_get_smart_status");
    int   (*disk_get_smart_temperature)(void*, int*) = (int(*)(void*, int*))dlsym(handle, "disk_get_smart_temperature");
    int   (*disk_get_smart_power_on_hours)(void*, int*) = (int(*)(void*, int*))dlsym(handle, "disk_get_smart_power_on_hours");
    int   (*disk_get_smart_reallocated_sectors)(void*, int*) = (int(*)(void*, int*))dlsym(handle, "disk_get_smart_reallocated_sectors");

    if (!disk_create || !disk_destroy || !disk_power_on || !disk_power_off || !disk_is_powered_on || !disk_get_size || !disk_read || !disk_write ||
        !disk_get_serial_number || !disk_get_manufacturer || !disk_get_model || !disk_get_firmware_version ||
        !disk_set_serial_number || !disk_set_manufacturer || !disk_set_model || !disk_set_firmware_version ||
        !disk_get_smart_attribute || !disk_set_smart_attribute || !disk_get_smart_status || !disk_get_smart_temperature ||
        !disk_get_smart_power_on_hours || !disk_get_smart_reallocated_sectors) {
        printf("符号加载失败\n");
        dlclose(handle);
        return 2;
    }

    void* disk = disk_create(DISK_FILE, DISK_SIZE);
    if (!disk) {
        printf("磁盘创建失败\n");
        dlclose(handle);
        return 3;
    }
    printf("磁盘创建成功，大小: %zu\n", disk_get_size(disk));

    // 测试磁盘信息查询功能
    printf("\n=== 测试磁盘信息查询功能 ===\n");
    
    char sn[64], manufacturer[64], model[64], firmware[32];
    
    // 查询默认磁盘信息
    if (disk_get_serial_number(disk, sn, sizeof(sn)) == 0) {
        printf("序列号: %s\n", sn);
    } else {
        printf("获取序列号失败\n");
    }
    
    if (disk_get_manufacturer(disk, manufacturer, sizeof(manufacturer)) == 0) {
        printf("厂商: %s\n", manufacturer);
    } else {
        printf("获取厂商信息失败\n");
    }
    
    if (disk_get_model(disk, model, sizeof(model)) == 0) {
        printf("型号: %s\n", model);
    } else {
        printf("获取型号信息失败\n");
    }
    
    if (disk_get_firmware_version(disk, firmware, sizeof(firmware)) == 0) {
        printf("固件版本: %s\n", firmware);
    } else {
        printf("获取固件版本失败\n");
    }

    // 测试设置磁盘信息
    printf("\n=== 测试设置磁盘信息功能 ===\n");
    
    if (disk_set_serial_number(disk, "CUSTOM123456789") == 0) {
        printf("设置序列号成功\n");
        if (disk_get_serial_number(disk, sn, sizeof(sn)) == 0) {
            printf("新序列号: %s\n", sn);
        }
    } else {
        printf("设置序列号失败\n");
    }
    
    if (disk_set_manufacturer(disk, "Custom Disk Corp.") == 0) {
        printf("设置厂商信息成功\n");
        if (disk_get_manufacturer(disk, manufacturer, sizeof(manufacturer)) == 0) {
            printf("新厂商: %s\n", manufacturer);
        }
    } else {
        printf("设置厂商信息失败\n");
    }
    
    if (disk_set_model(disk, "CUSTOM-2TB-HDD") == 0) {
        printf("设置型号信息成功\n");
        if (disk_get_model(disk, model, sizeof(model)) == 0) {
            printf("新型号: %s\n", model);
        }
    } else {
        printf("设置型号信息失败\n");
    }
    
    if (disk_set_firmware_version(disk, "v2.1.0") == 0) {
        printf("设置固件版本成功\n");
        if (disk_get_firmware_version(disk, firmware, sizeof(firmware)) == 0) {
            printf("新固件版本: %s\n", firmware);
        }
    } else {
        printf("设置固件版本失败\n");
    }

    // 测试厂商信息边界条件
    printf("\n=== 测试厂商信息边界条件 ===\n");
    
    // 测试缓冲区过小的情况
    char small_buf[5];
    if (disk_get_manufacturer(disk, small_buf, sizeof(small_buf)) == 0) {
        printf("小缓冲区厂商信息: %s\n", small_buf);
    } else {
        printf("小缓冲区获取厂商信息失败\n");
    }
    
    // 测试空指针
    if (disk_get_manufacturer(disk, nullptr, sizeof(manufacturer)) != 0) {
        printf("空指针测试通过\n");
    } else {
        printf("空指针测试失败\n");
    }
    
    // 测试零长度缓冲区
    if (disk_get_manufacturer(disk, manufacturer, 0) != 0) {
        printf("零长度缓冲区测试通过\n");
    } else {
        printf("零长度缓冲区测试失败\n");
    }

    // 测试SMART信息查询功能
    printf("\n=== 测试SMART信息查询功能 ===\n");
    
    int smart_status, temperature, power_hours, reallocated_sectors;
    
    // 查询SMART整体状态
    if (disk_get_smart_status(disk, &smart_status) == 0) {
        printf("SMART整体状态: %s\n", smart_status ? "正常" : "异常");
    } else {
        printf("获取SMART状态失败\n");
    }
    
    // 查询温度
    if (disk_get_smart_temperature(disk, &temperature) == 0) {
        printf("磁盘温度: %d°C\n", temperature);
    } else {
        printf("获取温度失败\n");
    }
    
    // 查询通电时间
    if (disk_get_smart_power_on_hours(disk, &power_hours) == 0) {
        printf("通电时间: %d小时\n", power_hours);
    } else {
        printf("获取通电时间失败\n");
    }
    
    // 查询重分配扇区数
    if (disk_get_smart_reallocated_sectors(disk, &reallocated_sectors) == 0) {
        printf("重分配扇区数: %d\n", reallocated_sectors);
    } else {
        printf("获取重分配扇区数失败\n");
    }

    // 测试SMART属性查询
    printf("\n=== 测试SMART属性查询 ===\n");
    
    int current, worst, threshold, raw_value;
    
    // 查询属性1: Raw Read Error Rate
    if (disk_get_smart_attribute(disk, 1, &current, &worst, &threshold, &raw_value) == 0) {
        printf("属性1 (Raw Read Error Rate): Current=%d, Worst=%d, Threshold=%d, Raw=%d\n", 
               current, worst, threshold, raw_value);
    }
    
    // 查询属性5: Reallocated Sectors Count
    if (disk_get_smart_attribute(disk, 5, &current, &worst, &threshold, &raw_value) == 0) {
        printf("属性5 (Reallocated Sectors): Current=%d, Worst=%d, Threshold=%d, Raw=%d\n", 
               current, worst, threshold, raw_value);
    }
    
    // 查询属性9: Power-On Hours
    if (disk_get_smart_attribute(disk, 9, &current, &worst, &threshold, &raw_value) == 0) {
        printf("属性9 (Power-On Hours): Current=%d, Worst=%d, Threshold=%d, Raw=%d\n", 
               current, worst, threshold, raw_value);
    }
    
    // 查询属性194: Temperature
    if (disk_get_smart_attribute(disk, 194, &current, &worst, &threshold, &raw_value) == 0) {
        printf("属性194 (Temperature): Current=%d, Worst=%d, Threshold=%d, Raw=%d\n", 
               current, worst, threshold, raw_value);
    }

    // 测试设置SMART属性
    printf("\n=== 测试设置SMART属性 ===\n");
    
    // 设置温度属性
    if (disk_set_smart_attribute(disk, 194, 60, 60, 0, 45) == 0) {
        printf("设置温度属性成功\n");
        if (disk_get_smart_attribute(disk, 194, &current, &worst, &threshold, &raw_value) == 0) {
            printf("新温度属性: Current=%d, Worst=%d, Threshold=%d, Raw=%d\n", 
                   current, worst, threshold, raw_value);
        }
    }
    
    // 设置重分配扇区属性
    if (disk_set_smart_attribute(disk, 5, 95, 95, 36, 2) == 0) {
        printf("设置重分配扇区属性成功\n");
        if (disk_get_smart_attribute(disk, 5, &current, &worst, &threshold, &raw_value) == 0) {
            printf("新重分配扇区属性: Current=%d, Worst=%d, Threshold=%d, Raw=%d\n", 
                   current, worst, threshold, raw_value);
        }
    }

    // 测试更多SMART属性
    printf("\n=== 测试更多SMART属性 ===\n");
    
    // 测试属性3: Spin Up Time
    if (disk_get_smart_attribute(disk, 3, &current, &worst, &threshold, &raw_value) == 0) {
        printf("属性3 (Spin Up Time): Current=%d, Worst=%d, Threshold=%d, Raw=%d\n", 
               current, worst, threshold, raw_value);
    }
    
    // 测试属性4: Start/Stop Count
    if (disk_get_smart_attribute(disk, 4, &current, &worst, &threshold, &raw_value) == 0) {
        printf("属性4 (Start/Stop Count): Current=%d, Worst=%d, Threshold=%d, Raw=%d\n", 
               current, worst, threshold, raw_value);
    }
    
    // 测试属性7: Seek Error Rate
    if (disk_get_smart_attribute(disk, 7, &current, &worst, &threshold, &raw_value) == 0) {
        printf("属性7 (Seek Error Rate): Current=%d, Worst=%d, Threshold=%d, Raw=%d\n", 
               current, worst, threshold, raw_value);
    }
    
    // 测试属性10: Spin Retry Count
    if (disk_get_smart_attribute(disk, 10, &current, &worst, &threshold, &raw_value) == 0) {
        printf("属性10 (Spin Retry Count): Current=%d, Worst=%d, Threshold=%d, Raw=%d\n", 
               current, worst, threshold, raw_value);
    }
    
    // 测试属性12: Power Cycles
    if (disk_get_smart_attribute(disk, 12, &current, &worst, &threshold, &raw_value) == 0) {
        printf("属性12 (Power Cycles): Current=%d, Worst=%d, Threshold=%d, Raw=%d\n", 
               current, worst, threshold, raw_value);
    }
    
    // 测试属性196: Reallocation Event Count
    if (disk_get_smart_attribute(disk, 196, &current, &worst, &threshold, &raw_value) == 0) {
        printf("属性196 (Reallocation Event Count): Current=%d, Worst=%d, Threshold=%d, Raw=%d\n", 
               current, worst, threshold, raw_value);
    }
    
    // 测试属性197: Current Pending Sectors
    if (disk_get_smart_attribute(disk, 197, &current, &worst, &threshold, &raw_value) == 0) {
        printf("属性197 (Current Pending Sectors): Current=%d, Worst=%d, Threshold=%d, Raw=%d\n", 
               current, worst, threshold, raw_value);
    }
    
    // 测试属性198: Offline Uncorrectable
    if (disk_get_smart_attribute(disk, 198, &current, &worst, &threshold, &raw_value) == 0) {
        printf("属性198 (Offline Uncorrectable): Current=%d, Worst=%d, Threshold=%d, Raw=%d\n", 
               current, worst, threshold, raw_value);
    }

    // 测试SMART属性边界条件和错误处理
    printf("\n=== 测试SMART属性边界条件和错误处理 ===\n");
    
    // 测试无效属性ID
    if (disk_get_smart_attribute(disk, -1, &current, &worst, &threshold, &raw_value) != 0) {
        printf("无效属性ID(-1)测试通过\n");
    } else {
        printf("无效属性ID(-1)测试失败\n");
    }
    
    if (disk_get_smart_attribute(disk, 256, &current, &worst, &threshold, &raw_value) != 0) {
        printf("无效属性ID(256)测试通过\n");
    } else {
        printf("无效属性ID(256)测试失败\n");
    }
    
    // 测试空指针
    if (disk_get_smart_attribute(disk, 1, nullptr, &worst, &threshold, &raw_value) != 0) {
        printf("SMART属性空指针测试通过\n");
    } else {
        printf("SMART属性空指针测试失败\n");
    }
    
    // 测试设置无效属性ID
    if (disk_set_smart_attribute(disk, -1, 100, 100, 50, 0) != 0) {
        printf("设置无效属性ID(-1)测试通过\n");
    } else {
        printf("设置无效属性ID(-1)测试失败\n");
    }
    
    if (disk_set_smart_attribute(disk, 256, 100, 100, 50, 0) != 0) {
        printf("设置无效属性ID(256)测试通过\n");
    } else {
        printf("设置无效属性ID(256)测试失败\n");
    }

    // 测试SMART状态边界条件
    printf("\n=== 测试SMART状态边界条件 ===\n");
    
    // 测试空指针
    if (disk_get_smart_status(disk, nullptr) != 0) {
        printf("SMART状态空指针测试通过\n");
    } else {
        printf("SMART状态空指针测试失败\n");
    }
    
    if (disk_get_smart_temperature(disk, nullptr) != 0) {
        printf("温度空指针测试通过\n");
    } else {
        printf("温度空指针测试失败\n");
    }
    
    if (disk_get_smart_power_on_hours(disk, nullptr) != 0) {
        printf("通电时间空指针测试通过\n");
    } else {
        printf("通电时间空指针测试失败\n");
    }
    
    if (disk_get_smart_reallocated_sectors(disk, nullptr) != 0) {
        printf("重分配扇区空指针测试通过\n");
    } else {
        printf("重分配扇区空指针测试失败\n");
    }

    // 测试厂商信息多次设置
    printf("\n=== 测试厂商信息多次设置 ===\n");
    
    const char* manufacturers[] = {
        "Western Digital",
        "Seagate Technology",
        "Toshiba Corporation",
        "Samsung Electronics",
        "Hitachi Global Storage"
    };
    
    for (int i = 0; i < 5; i++) {
        if (disk_set_manufacturer(disk, manufacturers[i]) == 0) {
            printf("设置厂商[%d]: %s\n", i, manufacturers[i]);
            if (disk_get_manufacturer(disk, manufacturer, sizeof(manufacturer)) == 0) {
                printf("验证厂商[%d]: %s\n", i, manufacturer);
            }
        }
    }

    // 测试SMART属性批量设置
    printf("\n=== 测试SMART属性批量设置 ===\n");
    
    struct {
        int id;
        int current;
        int worst;
        int threshold;
        int raw;
        const char* name;
    } test_attributes[] = {
        {1, 95, 95, 44, 10, "Raw Read Error Rate"},
        {5, 90, 90, 36, 5, "Reallocated Sectors"},
        {9, 85, 85, 0, 2000, "Power-On Hours"},
        {194, 70, 70, 0, 40, "Temperature"},
        {196, 100, 100, 0, 1, "Reallocation Event Count"}
    };
    
    for (int i = 0; i < 5; i++) {
        if (disk_set_smart_attribute(disk, test_attributes[i].id, 
                                   test_attributes[i].current, 
                                   test_attributes[i].worst, 
                                   test_attributes[i].threshold, 
                                   test_attributes[i].raw) == 0) {
            printf("设置%s成功\n", test_attributes[i].name);
            if (disk_get_smart_attribute(disk, test_attributes[i].id, 
                                       &current, &worst, &threshold, &raw_value) == 0) {
                printf("验证%s: Current=%d, Worst=%d, Threshold=%d, Raw=%d\n", 
                       test_attributes[i].name, current, worst, threshold, raw_value);
            }
        }
    }

    disk_power_on(disk);
    if (!disk_is_powered_on(disk)) {
        printf("磁盘上电失败\n");
        disk_destroy(disk);
        dlclose(handle);
        return 4;
    }
    printf("\n磁盘已上电\n");

    // 写入数据
    const char* msg = "HelloDisk";
    if (disk_write(disk, 0, msg, strlen(msg)+1) == 0) {
        printf("写入成功\n");
    } else {
        printf("写入失败\n");
    }

    // 读取数据
    char buf[64] = {0};
    if (disk_read(disk, 0, buf, strlen(msg)+1) == 0) {
        printf("读取成功: %s\n", buf);
    } else {
        printf("读取失败\n");
    }

    disk_power_off(disk);
    printf("磁盘已下电\n");
    disk_destroy(disk);
    dlclose(handle);
    return 0;
} 